package model

import (
	"context"
	"log"
	"poker/db"
	"sort"
	"strings"
	"sync"

	"go.mongodb.org/mongo-driver/bson"
)

// RankCache 单例结构体
type RankCache struct {
	mu    sync.Mutex
	cache map[string][]VoteDate // key: channel+appid, value: top 100
}

// UpdateUserScore 更新用户分数并调整排行榜
func (rc *RankCache) UpdateUserScore(channel string, appid string, user VoteDate) {
	rc.mu.Lock()
	defer rc.mu.Unlock()

	key := channel + appid
	users := rc.cache[key]
	if users == nil {
		users = make([]VoteDate, 0)
		rc.cache[key] = users
	}

	found := false

	// 查找用户并更新分数
	for i, u := range users {
		if u.Uid == user.Uid {
			users[i] = user // 更新分数
			found = true
			break
		}
	}

	// 如果用户不存在，尝试添加
	if !found {
		if len(users) < 100 {
			// 如果排行榜未满，直接添加
			users = append(users, user)
		} else {
			// 如果排行榜已满，比较新用户分数与最后一名
			lastUser := users[len(users)-1]
			if user.Score > lastUser.Score {
				// 替换最后一名
				users[len(users)-1] = user
			} else {
				// 如果新用户分数小于等于最后一名，不做处理
				return
			}
		}
	}

	// 重新排序
	sort.Slice(users, func(i, j int) bool {
		return users[i].Score > users[j].Score
	})

	// 更新缓存
	rc.cache[key] = users

	// 同步到数据库
	go rc.SyncToDatabase(channel, appid)
}

// SyncToDatabase 同步排行榜数据到数据库
func (rc *RankCache) SyncToDatabase(channel string, appid string) {
	rc.mu.Lock()
	users := rc.cache[channel+appid]
	if users == nil {
		return
	}
	rc.mu.Unlock()

	client := db.GetDB()
	col := channel + "_rank"
	collection := client.Collection(col)

	// 清空当前排行榜
	_, err := collection.DeleteMany(context.TODO(), bson.M{"appid": appid})
	if err != nil {
		log.Printf("Failed to clear rank collection for channel %s: %v", channel, err)
		return
	}

	// 将 []model.User 转换为 []interface{}
	var usersInterface []interface{}
	for _, user := range users {
		usersInterface = append(usersInterface, user)
	}

	// 插入新的排行榜数据
	_, err = collection.InsertMany(context.TODO(), usersInterface)
	if err != nil {
		log.Printf("Failed to sync rank data to database for channel %s: %v", channel, err)
		return
	}
	// log.Printf("Rank data for channel %s synced successfully", channel)
}

// 修改 GetTopUsers 方法
func (rc *RankCache) GetTopUsers(channel string, appid string) []VoteDate {
	rc.mu.Lock()
	defer rc.mu.Unlock()
	return rc.cache[channel+appid]
}

// LoadFromDatabase 从数据库加载排行榜数据到内存
func (rc *RankCache) LoadFromDatabase() {
	client := db.GetDB()
	collections, err := client.ListCollectionNames(context.TODO(), bson.M{})
	if err != nil {
		log.Printf("Failed to list collections: %v", err)
		return
	}

	for _, col := range collections {
		if !strings.HasSuffix(col, "_rank") {
			continue
		}
		// 提取 channel
		parts := strings.Split(col, "_")
		if len(parts) < 2 {
			log.Printf("Invalid collection name format: %s", col)
			continue
		}
		channel := strings.Join(parts[:len(parts)-1], "_") // 去掉最后的 "_rank"

		collection := client.Collection(col)

		var users []VoteDate
		cursor, err := collection.Find(context.TODO(), bson.M{})
		if err != nil {
			log.Printf("Failed to load rank data from database for collection %s: %v", col, err)
			continue
		}
		defer cursor.Close(context.TODO())

		if err := cursor.All(context.TODO(), &users); err != nil {
			log.Printf("Failed to decode rank data for collection %s: %v", col, err)
			continue
		}

		// 使用 channel+appid 作为缓存键
		for _, user := range users {
			key := channel + user.AppID
			rc.cache[key] = append(rc.cache[key], user)
		}
	}
}
